// #include "mainwindow.h"
// #include "ui_mainwindow.h"

// MainWindow::MainWindow(QWidget *parent)
//     : QMainWindow(parent)
//     , ui(new Ui::MainWindow)
// {
//     ui->setupUi(this);
// }

// MainWindow::~MainWindow()
// {
//     delete ui;
// }


#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileInfo>
#include <QScrollBar>
#include <QApplication>
#include <QClipboard>
#include <QRegularExpression>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , serialPort(nullptr)
    , dataPointCount(0)
{
    ui->setupUi(this);

    // 设置窗口属性
    setWindowTitle("Saber协议解析工具 - 欧拉角曲线绘制");
    setMinimumSize(1600, 1000);

    // 初始化UI
    setupUI();
    setupConnections();

    updateLog("就绪 - 请打开数据文件或连接串口");
}

MainWindow::~MainWindow()
{
    if (serialPort && serialPort->isOpen()) {
        serialPort->close();
    }
    delete serialPort;
    delete ui;
}

void MainWindow::setupUI()
{
    // 创建中央部件
    QWidget *centralWidget = new QWidget(this);
    setCentralWidget(centralWidget);

    // 创建主布局
    QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);

    // 顶部控制面板
    QWidget *controlPanel = new QWidget(this);
    QHBoxLayout *controlLayout = new QHBoxLayout(controlPanel);

    // 文件操作
    QGroupBox *fileGroup = new QGroupBox("文件操作", this);
    QVBoxLayout *fileLayout = new QVBoxLayout(fileGroup);
    openButton = new QPushButton("打开TXT文件", this);
    fileLayout->addWidget(openButton);

    // 串口操作
    QGroupBox *serialGroup = new QGroupBox("串口操作", this);
    QVBoxLayout *serialLayout = new QVBoxLayout(serialGroup);

    QHBoxLayout *serialConfigLayout = new QHBoxLayout();
    serialPortComboBox = new QComboBox(this);
    baudRateComboBox = new QComboBox(this);
    baudRateComboBox->addItems({"9600", "115200", "230400", "460800", "921600"});
    baudRateComboBox->setCurrentText("115200");

    // 刷新串口列表
    QPushButton *refreshSerialButton = new QPushButton("刷新", this);
    connect(refreshSerialButton, &QPushButton::clicked, [this]() {
        serialPortComboBox->clear();
        foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
            serialPortComboBox->addItem(info.portName());
        }
    });
    refreshSerialButton->click(); // 初始刷新

    serialConfigLayout->addWidget(new QLabel("端口:", this));
    serialConfigLayout->addWidget(serialPortComboBox);
    serialConfigLayout->addWidget(new QLabel("波特率:", this));
    serialConfigLayout->addWidget(baudRateComboBox);
    serialConfigLayout->addWidget(refreshSerialButton);

    QHBoxLayout *serialButtonLayout = new QHBoxLayout();
    openSerialButton = new QPushButton("打开串口", this);
    closeSerialButton = new QPushButton("关闭串口", this);
    closeSerialButton->setEnabled(false);
    serialButtonLayout->addWidget(openSerialButton);
    serialButtonLayout->addWidget(closeSerialButton);

    serialLayout->addLayout(serialConfigLayout);
    serialLayout->addLayout(serialButtonLayout);

    // 帧头设置
    QGroupBox *headerGroup = new QGroupBox("帧头设置", this);
    QVBoxLayout *headerLayout = new QVBoxLayout(headerGroup);
    frameHeaderInput = new QLineEdit(this);
    frameHeaderInput->setText(DEFAULT_FRAME_HEADER.toHex(' ').toUpper());
    frameHeaderInput->setPlaceholderText("输入帧头十六进制 (如: 41 78 FF 06 81 44)");
    headerLayout->addWidget(frameHeaderInput);

    searchButton = new QPushButton("搜索帧头", this);
    parseButton = new QPushButton("解析数据", this);
    clearButton = new QPushButton("清空所有", this);
    autoParseCheck = new QCheckBox("自动解析", this);
    autoParseCheck->setChecked(true);

    headerLayout->addWidget(searchButton);
    headerLayout->addWidget(parseButton);
    headerLayout->addWidget(clearButton);
    headerLayout->addWidget(autoParseCheck);

    // 添加到控制面板
    controlLayout->addWidget(fileGroup);
    controlLayout->addWidget(serialGroup);
    controlLayout->addWidget(headerGroup);

    // 中部显示区域
    QWidget *displayPanel = new QWidget(this);
    QHBoxLayout *displayLayout = new QHBoxLayout(displayPanel);

    // 左侧十六进制显示
    QGroupBox *hexGroup = new QGroupBox("十六进制数据", this);
    QVBoxLayout *hexLayout = new QVBoxLayout(hexGroup);
    hexDisplayTextEdit = new QTextEdit(this);
    hexDisplayTextEdit->setReadOnly(true);
    hexDisplayTextEdit->setFont(QFont("Consolas", 8));
    hexLayout->addWidget(hexDisplayTextEdit);

    // 右侧图表
    QGroupBox *chartGroup = new QGroupBox("欧拉角曲线", this);
    QVBoxLayout *chartLayout = new QVBoxLayout(chartGroup);

    // 初始化图表
    chart = new QChart();
    chartView = new QChartView(chart);
    chartView->setRenderHint(QPainter::Antialiasing);

    rollSeries = new QLineSeries();
    rollSeries->setName("Roll");
    rollSeries->setColor(Qt::red);

    pitchSeries = new QLineSeries();
    pitchSeries->setName("Pitch");
    pitchSeries->setColor(Qt::green);

    yawSeries = new QLineSeries();
    yawSeries->setName("Yaw");
    yawSeries->setColor(Qt::blue);

    chart->addSeries(rollSeries);
    chart->addSeries(pitchSeries);
    chart->addSeries(yawSeries);

    axisX = new QValueAxis();
    axisY = new QValueAxis();
    axisY->setRange(-180, 180);
    axisY->setTitleText("角度 (°)");
    axisX->setTitleText("数据点");

    chart->addAxis(axisX, Qt::AlignBottom);
    chart->addAxis(axisY, Qt::AlignLeft);

    rollSeries->attachAxis(axisX);
    rollSeries->attachAxis(axisY);
    pitchSeries->attachAxis(axisX);
    pitchSeries->attachAxis(axisY);
    yawSeries->attachAxis(axisX);
    yawSeries->attachAxis(axisY);

    chart->setTitle("欧拉角实时曲线");
    chartLayout->addWidget(chartView);

    displayLayout->addWidget(hexGroup, 1);
    displayLayout->addWidget(chartGroup, 2);

    // 底部日志
    QGroupBox *logGroup = new QGroupBox("日志", this);
    QVBoxLayout *logLayout = new QVBoxLayout(logGroup);
    logTextEdit = new QTextEdit(this);
    logTextEdit->setReadOnly(true);
    logTextEdit->setMaximumHeight(120);
    logTextEdit->setFont(QFont("Consolas", 9));
    logLayout->addWidget(logTextEdit);

    // 添加到主布局
    mainLayout->addWidget(controlPanel);
    mainLayout->addWidget(displayPanel);
    mainLayout->addWidget(logGroup);

    // 设置样式
    QString buttonStyle = "QPushButton { padding: 6px; font-weight: bold; }";
    openButton->setStyleSheet(buttonStyle + "background-color: #4CAF50; color: white;");
    openSerialButton->setStyleSheet(buttonStyle + "background-color: #2196F3; color: white;");
    closeSerialButton->setStyleSheet(buttonStyle + "background-color: #FF9800; color: white;");
    searchButton->setStyleSheet(buttonStyle + "background-color: #9C27B0; color: white;");
    parseButton->setStyleSheet(buttonStyle + "background-color: #673AB7; color: white;");
    clearButton->setStyleSheet(buttonStyle + "background-color: #F44336; color: white;");
}

void MainWindow::setupConnections()
{
    connect(openButton, &QPushButton::clicked, this, &MainWindow::openTextFile);
    connect(searchButton, &QPushButton::clicked, this, &MainWindow::searchFrameHeader);
    connect(parseButton, &QPushButton::clicked, this, &MainWindow::parseData);
    connect(clearButton, &QPushButton::clicked, this, &MainWindow::clearAll);
    connect(openSerialButton, &QPushButton::clicked, this, &MainWindow::openSerialPort);
    connect(closeSerialButton, &QPushButton::clicked, this, &MainWindow::closeSerialPort);
}

void MainWindow::updateLog(const QString &message)
{
    logTextEdit->append(QDateTime::currentDateTime().toString("[yyyy-MM-dd hh:mm:ss] ") + message);
    logTextEdit->verticalScrollBar()->setValue(logTextEdit->verticalScrollBar()->maximum());
}

QByteArray MainWindow::hexStringToByteArray(const QString &hexString)
{
    QByteArray byteArray;
    QString cleanedString = hexString;

    // 移除所有非十六进制字符
    cleanedString.remove(QRegularExpression("[^0-9A-Fa-f]"));

    for (int i = 0; i < cleanedString.length(); i += 2) {
        QString byteString = cleanedString.mid(i, 2);
        if (byteString.length() == 2) {
            bool ok;
            char byte = static_cast<char>(byteString.toInt(&ok, 16));
            if (ok) {
                byteArray.append(byte);
            }
        }
    }

    return byteArray;
}

void MainWindow::openTextFile()
{
    QString fileName = QFileDialog::getOpenFileName(
        this,
        "选择数据文件",
        QDir::homePath(),
        "文本文件 (*.txt);;所有文件 (*)"
        );

    if (fileName.isEmpty()) {
        updateLog("取消打开文件");
        return;
    }

    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QMessageBox::warning(this, "错误", "无法打开文件: " + file.errorString());
        return;
    }

    QTextStream in(&file);
    QString content = in.readAll();
    file.close();

    // 转换文本内容为二进制数据
    fileData = hexStringToByteArray(content);
    currentFilePath = fileName;

    QFileInfo fileInfo(fileName);
    QString fileInfoText = QString("文件: %1 | 大小: %2 字节 | 转换后: %3 字节")
                               .arg(fileInfo.fileName())
                               .arg(fileInfo.size())
                               .arg(fileData.size());

    updateLog(fileInfoText);
    displayHexData();

    if (autoParseCheck->isChecked()) {
        searchFrameHeader();
    }
}

void MainWindow::displayHexData()
{
    hexDisplayTextEdit->clear();
    QString hexDisplay;

    for (int i = 0; i < fileData.size(); ++i) {
        if (i % 16 == 0) {
            if (i > 0) hexDisplay += "\n";
            hexDisplay += QString("%1: ").arg(i, 4, 16, QChar('0')).toUpper();
        }
        hexDisplay += QString("%1 ").arg(static_cast<unsigned char>(fileData[i]), 2, 16, QChar('0')).toUpper();
    }

    hexDisplayTextEdit->setPlainText(hexDisplay);
}

void MainWindow::searchFrameHeader()
{
    if (fileData.isEmpty()) {
        QMessageBox::warning(this, "错误", "请先打开数据文件");
        return;
    }

    // 获取帧头
    QString headerText = frameHeaderInput->text().trimmed();
    if (headerText.isEmpty()) {
        headerText = DEFAULT_FRAME_HEADER.toHex(' ').toUpper();
        frameHeaderInput->setText(headerText);
    }

    QByteArray frameHeader = QByteArray::fromHex(headerText.remove(' ').toLatin1());
    if (frameHeader.isEmpty()) {
        QMessageBox::warning(this, "错误", "无效的帧头格式");
        return;
    }

    updateLog(QString("开始搜索帧头: %1").arg(frameHeader.toHex(' ').toUpper()));

    QElapsedTimer timer;
    timer.start();

    // 搜索帧头
    framePositions.clear();
    for (int i = 0; i <= fileData.size() - frameHeader.size(); ++i) {
        bool match = true;
        for (int j = 0; j < frameHeader.size(); ++j) {
            if (fileData[i + j] != frameHeader[j]) {
                match = false;
                break;
            }
        }
        if (match) {
            framePositions.append(i);
        }
    }

    qint64 elapsed = timer.elapsed();
    updateLog(QString("找到 %1 个帧头, 耗时: %2 ms").arg(framePositions.size()).arg(elapsed));

    if (!framePositions.isEmpty()) {
        if (autoParseCheck->isChecked()) {
            parseData();
        }
    }
}



Vector3F MainWindow::parseCalibrationData(const QByteArray &data, int offset)
{
    Vector3F result = {0, 0, 0};

    if (offset + 11 < data.size()) {
        UToF converter;

        converter.u[0] = static_cast<unsigned char>(data[offset]);
        converter.u[1] = static_cast<unsigned char>(data[offset + 1]);
        converter.u[2] = static_cast<unsigned char>(data[offset + 2]);
        converter.u[3] = static_cast<unsigned char>(data[offset + 3]);
        result.x = converter.f;

        converter.u[0] = static_cast<unsigned char>(data[offset + 4]);
        converter.u[1] = static_cast<unsigned char>(data[offset + 5]);
        converter.u[2] = static_cast<unsigned char>(data[offset + 6]);
        converter.u[3] = static_cast<unsigned char>(data[offset + 7]);
        result.y = converter.f;

        converter.u[0] = static_cast<unsigned char>(data[offset + 8]);
        converter.u[1] = static_cast<unsigned char>(data[offset + 9]);
        converter.u[2] = static_cast<unsigned char>(data[offset + 10]);
        converter.u[3] = static_cast<unsigned char>(data[offset + 11]);
        result.z = converter.f;
    }

    return result;
}

Vector3S MainWindow::parseRawData(const QByteArray &data, int offset)
{
    Vector3S result = {0, 0, 0};

    if (offset + 5 < data.size()) {
        UToS converter;

        converter.c[0] = data[offset];
        converter.c[1] = data[offset + 1];
        result.x = converter.s;

        converter.c[0] = data[offset + 2];
        converter.c[1] = data[offset + 3];
        result.y = converter.s;

        converter.c[0] = data[offset + 4];
        converter.c[1] = data[offset + 5];
        result.z = converter.s;
    }

    return result;
}

// Vector3F MainWindow::parseEulerData(const QByteArray &data, int offset)
// {
//     Vector3F result = {0, 0, 0};

//     if (offset + 11 < data.size()) {
//         UToF converter;

//         // 小端字节序：低位在前
//         converter.u[0] = static_cast<unsigned char>(data[offset]);
//         converter.u[1] = static_cast<unsigned char>(data[offset + 1]);
//         converter.u[2] = static_cast<unsigned char>(data[offset + 2]);
//         converter.u[3] = static_cast<unsigned char>(data[offset + 3]);
//         result.x = converter.f;

//         converter.u[0] = static_cast<unsigned char>(data[offset + 4]);
//         converter.u[1] = static_cast<unsigned char>(data[offset + 5]);
//         converter.u[2] = static_cast<unsigned char>(data[offset + 6]);
//         converter.u[3] = static_cast<unsigned char>(data[offset + 7]);
//         result.y = converter.f;

//         converter.u[0] = static_cast<unsigned char>(data[offset + 8]);
//         converter.u[1] = static_cast<unsigned char>(data[offset + 9]);
//         converter.u[2] = static_cast<unsigned char>(data[offset + 10]);
//         converter.u[3] = static_cast<unsigned char>(data[offset + 11]);
//         result.z = converter.f;
//     }

//     return result;
// }

// Vector3F MainWindow::parseEulerData(const QByteArray &data, int offset)
// {
//     Vector3F result = {0, 0, 0};

//     if (offset + 11 < data.size()) {
//         // 欧拉角数据通常是大端字节序（网络字节序）
//         // 从高位到低位：byte3 byte2 byte1 byte0
//         result.x = qFromBigEndian<float>(reinterpret_cast<const uchar*>(data.constData() + offset));
//         result.y = qFromBigEndian<float>(reinterpret_cast<const uchar*>(data.constData() + offset + 4));
//         result.z = qFromBigEndian<float>(reinterpret_cast<const uchar*>(data.constData() + offset + 8));
//     }

//     return result;
// }
Vector3F MainWindow::parseEulerData(const QByteArray &data, int offset)
{
    Vector3F result = {0, 0, 0};

    if (offset + 11 >= data.size()) {
        updateLog("欧拉角数据长度不足");
        return result;
    }

    // 方法1: 使用memcpy确保字节序正确
    float x, y, z;

    // 复制字节数据
    memcpy(&x, data.constData() + offset, sizeof(float));
    memcpy(&y, data.constData() + offset + 4, sizeof(float));
    memcpy(&z, data.constData() + offset + 8, sizeof(float));

// 根据实际情况调整字节序
// 如果数据是大端字节序，需要转换
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
    // 假设数据是大端字节序，需要转换为小端
    x = qFromBigEndian<float>(reinterpret_cast<const uchar*>(data.constData() + offset));
    y = qFromBigEndian<float>(reinterpret_cast<const uchar*>(data.constData() + offset + 4));
    z = qFromBigEndian<float>(reinterpret_cast<const uchar*>(data.constData() + offset + 8));
#endif

    result.x = x;
    result.y = y;
    result.z = z;

    return result;
}


QString MainWindow::vector3FToString(const Vector3F &vec)
{
    return QString("X:%1 Y:%2 Z:%3").arg(vec.x, 0, 'f', 3).arg(vec.y, 0, 'f', 3).arg(vec.z, 0, 'f', 3);
}

QString MainWindow::vector3SToString(const Vector3S &vec)
{
    return QString("X:%1 Y:%2 Z:%3").arg(vec.x).arg(vec.y).arg(vec.z);
}

bool MainWindow::parseSensorData(const QByteArray &frameData, SensorData &sensorData)
{
    int pos = 0;
    int frameLength = frameData.size();

    // 跳过帧头 (6字节)
    pos += 6;

    while (pos < frameLength - 2) {
        // 读取PID
        quint16 pid = (static_cast<quint8>(frameData[pos + 1]) << 8) | static_cast<quint8>(frameData[pos]);
        pos += 2;

        if (pos >= frameLength) break;

        // 读取数据长度
        quint8 dataLength = static_cast<quint8>(frameData[pos]);
        pos += 1;

        if (pos + dataLength > frameLength) break;

        // 根据PID解析数据
        switch (pid) {
        case 0x8800: // Saber_Cal_Acc
            if (dataLength >= 12) {
                sensorData.accel = parseCalibrationData(frameData, pos);
            }
            break;

        case 0x8C00: // Saber_Cal_Gyro
            if (dataLength >= 12) {
                sensorData.gyro = parseCalibrationData(frameData, pos);
            }
            break;

        // case 0xB001: // Saber_Euler (欧拉角)
        //     if (dataLength >= 12) {
        //         sensorData
        //             .euler = parseEulerData(frameData, pos);
        //         // 添加调试输出
        //         updateLog(QString("Euler parsed - Roll: %1, Pitch: %2, Yaw: %3")
        //                       .arg(sensorData.euler.x)
        //                       .arg(sensorData.euler.y)
        //                       .arg(sensorData.euler.z));
        //     }
        //     break;

        case 0xB001: // Saber_Euler (欧拉角)
            if (dataLength >= 12) {
                sensorData
                    .euler = parseEulerData(frameData, pos);

                // 调试输出原始字节
                QByteArray eulerBytes
                    = frameData.mid(pos, 12);
                QString hexBytes
                    ;
                for (int i = 0; i < eulerBytes.size(); ++i) {
                    hexBytes
                        += QString("%1 ").arg(static_cast<unsigned char>(eulerBytes[i]), 2, 16, QChar('0')).toUpper();
                }

                updateLog(QString("欧拉角原始数据: %1").arg(hexBytes));
                updateLog(QString("解析结果 - Roll: %1, Pitch: %2, Yaw: %3")
                              .arg(sensorData.euler.x, 0, 'f', 3)
                              .arg(sensorData.euler.y, 0, 'f', 3)
                              .arg(sensorData.euler.z, 0, 'f', 3));
            }
            break;


        case 0x8401: // Raw Gyro
            if (dataLength >= 6) {
                sensorData.rawGyro = parseRawData(frameData, pos);
            }

            break;

        case 0x8801: // Raw Acc
            if (dataLength >= 6) {
                sensorData.rawAccel = parseRawData(frameData, pos);
            }
            break;
        }

        pos += dataLength;


        // 在 parseSensorData 中添加
        updateLog(QString("PID: 0x%1, Data length: %2, Pos: %3")
                      .arg(pid, 4, 16, QChar('0'))
                      .arg(dataLength)
                      .arg(pos));
    }


    sensorData.timestamp = QDateTime::currentMSecsSinceEpoch();
    return true;
}



void MainWindow::parseData()
{
    if (framePositions.isEmpty()) {
        QMessageBox::information(this, "提示", "请先搜索帧头");
        return;
    }

    parsedData.clear();
    dataPointCount = 0;

    QElapsedTimer timer;
    timer.start();

    int successCount = 0;

    QProgressDialog progress("解析数据...", "取消", 0, framePositions.size(), this);
    progress.setWindowModality(Qt::WindowModal);

    for (int i = 0; i < framePositions.size(); ++i) {
        progress.setValue(i);
        if (progress.wasCanceled()) break;

        int startPos = framePositions[i];
        int endPos = (i < framePositions.size() - 1) ? framePositions[i + 1] : fileData.size();
        int frameLength = endPos - startPos;

        if (frameLength < 20) continue; // 最小帧长度

        QByteArray frameData = fileData.mid(startPos, frameLength);

        SensorData sensorData = {};
        if (parseSensorData(frameData, sensorData)) {
            parsedData.append(sensorData);
            successCount++;

            // 更新图表
            rollSeries->append(dataPointCount, sensorData.euler.x);
            pitchSeries->append(dataPointCount, sensorData.euler.y);
            yawSeries->append(dataPointCount, sensorData.euler.z);
            dataPointCount++;

            if (successCount % 10 == 0) {
                updateChart();
            }
        }
    }

    progress.setValue(framePositions.size());

    // 更新图表范围
    if (dataPointCount > 0) {
        axisX->setRange(0, dataPointCount);
        chartView->update();
    }

    qint64 elapsed = timer.elapsed();
    updateLog(QString("解析完成! 成功解析 %1/%2 帧数据, 耗时: %3 ms")
                  .arg(successCount).arg(framePositions.size()).arg(elapsed));
}

void MainWindow::clearAll()
{
    fileData.clear();
    parsedData.clear();
    framePositions.clear();
    currentFilePath = "";
    hexDisplayTextEdit->clear();
    logTextEdit->clear();

    // 清空图表
    rollSeries->clear();
    pitchSeries->clear();
    yawSeries->clear();
    dataPointCount = 0;

    updateLog("已清空所有数据");
}

void MainWindow::openSerialPort()
{
    if (serialPort && serialPort->isOpen()) {
        serialPort->close();
        delete serialPort;
    }

    serialPort = new QSerialPort(this);
    serialPort->setPortName(serialPortComboBox->currentText());
    serialPort->setBaudRate(baudRateComboBox->currentText().toInt());
    serialPort->setDataBits(QSerialPort::Data8);
    serialPort->setParity(QSerialPort::NoParity);
    serialPort->setStopBits(QSerialPort::OneStop);
    serialPort->setFlowControl(QSerialPort::NoFlowControl);

    if (serialPort->open(QIODevice::ReadOnly)) {
        updateLog(QString("串口已打开: %1, %2 baud")
                      .arg(serialPort->portName())
                      .arg(serialPort->baudRate()));

        openSerialButton->setEnabled(false);
        closeSerialButton->setEnabled(true);

        connect(serialPort, &QSerialPort::readyRead, this, &MainWindow::readSerialData);
    } else {
        QMessageBox::warning(this, "错误", "无法打开串口: " + serialPort->errorString());
        updateLog("串口打开失败: " + serialPort->errorString());
    }
}

void MainWindow::closeSerialPort()
{
    if (serialPort && serialPort->isOpen()) {
        serialPort->close();
        updateLog("串口已关闭");
        openSerialButton->setEnabled(true);
        closeSerialButton->setEnabled(false);
    }
}

// void MainWindow::readSerialData()
// {
//     if (!serialPort || !serialPort->isOpen()) return;

//     QByteArray data = serialPort->readAll();
//     fileData.append(data);

//     // 实时显示数据
//     QString hexData;
//     for (int i = 0; i < data.size(); ++i) {
//         hexData += QString("%1 ").arg(static_cast<unsigned char>(data[i]), 2, 16, QChar('0')).toUpper();
//     }
//     hexDisplayTextEdit->moveCursor(QTextCursor::End);
//     hexDisplayTextEdit->insertPlainText(hexData);
//     hexDisplayTextEdit->moveCursor(QTextCursor::End);

//     // 实时解析
//     static QByteArray buffer;
//     buffer.append(data);

//     // 获取帧头
//     QString headerText = frameHeaderInput->text().trimmed();
//     QByteArray frameHeader = QByteArray::fromHex(headerText.remove(' ').toLatin1());

//     // 搜索帧头并解析
//     int pos = 0;
//     while ((pos = buffer.indexOf(frameHeader, pos)) != -1) {
//         if (pos + 50 <= buffer.size()) { // 假设最小帧长度
//             QByteArray frameData = buffer.mid(pos, 100); // 取足够长的数据

//             SensorData sensorData = {};
//             if (parseSensorData(frameData, sensorData)) {
//                 // 更新图表
//                 rollSeries->append(dataPointCount, sensorData.euler.x);
//                 pitchSeries->append(dataPointCount, sensorData.euler.y);
//                 yawSeries->append(dataPointCount, sensorData.euler.z);
//                 dataPointCount++;

//                 // 自动调整图表范围
//                 if (dataPointCount % 100 == 0) {
//                     axisX->setRange(qMax(0, dataPointCount - 500), dataPointCount + 100);
//                 }
//             }

//             pos += frameHeader.size();
//         } else {
//             break;
//         }
//     }

//     // 保持缓冲区大小合理
//     if (buffer.size() > 10000) {
//         buffer = buffer.right(5000);
//     }
// }



void MainWindow::readSerialData()
{
    if (!serialPort || !serialPort->isOpen()) return;

    QByteArray data = serialPort->readAll();
    fileData.append(data);

    // 实时显示数据（优化性能）
    static int displayCounter = 0;
    if (++displayCounter % 10 == 0) { // 每10次更新一次显示
        hexDisplayTextEdit->moveCursor(QTextCursor::End);
        hexDisplayTextEdit->insertPlainText(data.toHex(' ').toUpper() + " ");
        hexDisplayTextEdit->moveCursor(QTextCursor::End);
        displayCounter = 0;
    }

    // 获取帧头
    QString headerText = frameHeaderInput->text().trimmed();
    QByteArray frameHeader = QByteArray::fromHex(headerText.remove(' ').toLatin1());
    if (frameHeader.isEmpty()) return;

    // 搜索帧头并解析
    static QByteArray serialBuffer;
    serialBuffer.append(data);

    int pos = 0;
    while ((pos = serialBuffer.indexOf(frameHeader, pos)) != -1) {
        // 检查是否有完整的一帧数据（假设帧长度至少为50字节）
        if (pos + 50 <= serialBuffer.size()) {
            // 尝试找到帧结束（下一个帧头或缓冲区末尾）
            int nextHeader = serialBuffer.indexOf(frameHeader, pos + frameHeader.size());
            int frameLength = (nextHeader == -1) ? serialBuffer.size() - pos : nextHeader - pos;

            if (frameLength >= 50) { // 确保有足够的数据
                QByteArray frameData = serialBuffer.mid(pos, frameLength);

                SensorData sensorData = {};
                if (parseSensorData(frameData, sensorData)) {
                    parsedData.append(sensorData);

                    // 更新图表
                    rollSeries->append(dataPointCount, sensorData.euler.x);
                    pitchSeries->append(dataPointCount, sensorData.euler.y);
                    yawSeries->append(dataPointCount, sensorData.euler.z);
                    dataPointCount++;

                    // 定期更新图表
                    if (dataPointCount % 10 == 0) {
                        updateChart();
                    }

                    // 显示解析结果
                    updateLog(QString("欧拉角 - Roll: %1°, Pitch: %2°, Yaw: %3°")
                                  .arg(sensorData.euler.x, 0, 'f', 2)
                                  .arg(sensorData.euler.y, 0, 'f', 2)
                                  .arg(sensorData.euler.z, 0, 'f', 2));
                }
            }

            // 移动到下一个位置
            pos += frameLength;
        } else {
            break; // 数据不完整，等待更多数据
        }
    }

    // 清理已处理的数据
    if (pos > 0) {
        serialBuffer = serialBuffer.mid(pos);
    }

    // 限制缓冲区大小
    if (serialBuffer.size() > 10000) {
        serialBuffer = serialBuffer.right(5000);
    }
}

// void MainWindow::updateChart()
// {
//     chartView->update();
// }


void MainWindow::updateChart()
{
    if (dataPointCount == 0) return;

    // 自动调整X轴范围，显示最近500个数据点
    int startX = qMax(0, dataPointCount - 500);
    int endX = dataPointCount;

    axisX
        ->setRange(startX, endX);
    chartView
        ->update();
}
